﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace Porter
{

    public static class FlashCardUtils
    {
        public const int MAX_PATH = 260;

        //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/apisp/html/sp__wcesdk_findfirstflashcard.asp
        //HANDLE FindFirstFlashCard(
        //  LPWIN32_FIND_DATA lpFindFlashData
        //);
        [DllImport("note_prj.dll")]
        public static extern IntPtr FindFirstFlashCard(out Win32FindData findData);

        public struct FILETIME
        {
            Int32 dwLowDateTime;
            Int32 dwHighDateTime;
        }

        //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcedata5/html/wce50lrfWIN32FINDDATA.asp
        /// <summary>
        /// 
        /// </summary>
        /// <remarks>
        /// 
        /// </remarks>
        /// <author>Jon Froehlich</author>
        //typedef struct _WIN32_FIND_DATA { 
        //  DWORD dwFileAttributes; 
        //  FILETIME ftCreationTime; 
        //  FILETIME ftLastAccessTime; 
        //  FILETIME ftLastWriteTime; 
        //  DWORD nFileSizeHigh; 
        //  DWORD nFileSizeLow; 
        //  DWORD dwOID; 
        //  TCHAR cFileName[MAX_PATH]; 
        //} WIN32_FIND_DATA; 
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        /// <summary>
        /// 
        /// </summary>
        /// <remarks>
        /// 
        /// </remarks>
        /// <author>Jon Froehlich</author>
        public struct Win32FindData
        {
            public uint dwFileAttributes;
            public FILETIME ftCreationTime;
            public FILETIME ftLastAccessTime;
            public FILETIME ftLastWriteTime;
            public uint nFileSizeHigh;
            public uint nFileSizeLow;
            public uint dwOID;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
            public string cFileName;
        }

        //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcedata5/html/wce50lrffindclose.asp
        //BOOL FindClose( 
        //  HANDLE hFindFile 
        //); 
        [DllImport("coredll.dll")]
        public static extern bool FindClose(IntPtr hFindFile);

        public static String GetFirstFlashCardPath()
        {
            Win32FindData win32FindData;
            IntPtr intPtr = FindFirstFlashCard(out win32FindData);
            String path = win32FindData.cFileName;
            FindClose(intPtr);

            if (String.IsNullOrEmpty(path))
            {
                throw new System.IO.FileNotFoundException("Could not find a flash card on this device");
            }

            return path;
        }

        public static bool FlashCardExists()
        {
            try
            {
                string flashCardPath = GetFirstFlashCardPath();
                return !String.IsNullOrEmpty(flashCardPath);
            }
            catch (System.IO.FileNotFoundException rnfe)
            {
                Debug.WriteLine(rnfe.Message);
                return false;
            }
        }

        public static long GetStorageCardSizeInBytes()
        {
            if (!FlashCardExists()) { return 0; }

            string storageCardPath = GetFirstFlashCardPath();
            ulong byteAvailableToCaller, totalNumOfBytes, totalNumOfFreeBytes;
            GetDiskFreeSpaceEx(storageCardPath, out byteAvailableToCaller, out totalNumOfBytes, out totalNumOfFreeBytes);
            return (long)totalNumOfBytes;
        }

        public static long GetStorageCardFreeSpaceInBytes()
        {
            if (!FlashCardExists()) { return 0; }

            string storageCardPath = GetFirstFlashCardPath();
            ulong byteAvailableToCaller, totalNumOfBytes, totalNumOfFreeBytes;
            GetDiskFreeSpaceEx(storageCardPath, out byteAvailableToCaller, out totalNumOfBytes, out totalNumOfFreeBytes);
            return (long)totalNumOfFreeBytes;
        }

        [DllImport("coredll.dll")]
        private static extern bool GetDiskFreeSpaceEx(
                string lpDirectoryName,
                out ulong lpFreeBytesAvailableToCaller,
                out ulong lpTotalNumberOfBytes,
                out ulong lpTotalNumberOfFreeBytes
                );
    }
}
